/*
 * Copyright 2014 by État de Genève (Switzerland)
 * All rights reserved.
 *
 * Author: ELCA Informatique SA
 */
define(['durandal/system',
        'services/config', 
        'services/notifier',
        'services/user',
        'q',
        'i18n'],
    function (system, config, notifier, user, Q, i18n) {

        var apiUrl = config.api.baseUrl;

        return {
            get: basicGet,
            post: basicPost,
            getJsonFile: getJsonFile
        };

        function basicGet(url, data) {
            return Q($.ajax({
	                    url: apiUrl + '/' + url,
	                    data: data,
	                    type: 'GET',
	                    contentType: 'application/json',
	                    dataType: 'json',
	                    xhrFields: {
	                        withCredentials: true
	                    }
	                })
	            )
                .then(parseRes)
                .catch(handleApiError.bind(undefined, url, data));
        }

        function basicPost(url, data) {
            return Q($.ajax({
	                    url: apiUrl + '/' + url,
	                    data: ko.toJSON(data),
	                    type: 'POST',
	                    contentType: 'application/json',
	                    dataType: 'json',
	                    xhrFields: {
	                        withCredentials: true
	                    }
	                })
	            )
                .then(parseRes)
                .catch(handleApiError.bind(undefined, url, data));
        }

        function getJsonFile(fileUrl) {
            return Q(
                $.ajax({
                    url: config.app.resourceUrl + '/' + fileUrl,
                    type: 'GET',
                    xhrFields: {
                        withCredentials: true
                    }
                })
            )
                .then(parseRes)
                .catch(handleApiError.bind(undefined, fileUrl, null));
        }

        function parseRes(data) {
            if(typeof data === 'string') {
            	data = ko.utils.parseJson(data);
            }
            user.setVersion(data.result.revision);
            return data;
        }

        /**
         * Handles all API errors (network errors, server errors, etc...)
         */
        function handleApiError(url, data, xhr) {

            var E = null;
            var req = apiUrl + '/' + url + ' (' + (data || '') + ')';
            // make sure error generation does not throw an error without code and apiStack properties
            try {

                var code = xhr.status;
                var err = xhr.statusText;
                var body = '';
                try {
                    body = ko.utils.parseJson(xhr.responseText);
                } catch (err) {
                    body = xhr.responseText;
                }
                // report error to system
                notifier.log(code, err, body);

                // build new error to throw back
                E = new Error(i18n.t('cms:error.' + code, { defaultValue: err }));
                E.apiStack = body;
                E.code = xhr.status;
                E.req = req;

            } catch (e) {
                E = e;
                E.apiStack = '';
                E.code = 0;
                E.req = req;
            }

            // propagate Error with aditional info for next modules to handle it
            throw E;
        }
    });
